/*
 * Automata.c
 * Behavioral Attributed Automaton
 * @author Gregoire JACOB (gregoire.jacob@orange-ftgroup.com)
 * @date 01/12/2008
 * @version 2.2
 * Automaton structures
 */

#include ".\Includes\BehaviorAutomata.h"


/* Access functions ****************************************************/
char getCurrentState(struct PARSED_AUTOMATON * parautomaton){
	int position = parautomaton->nbnode-1;
	return parautomaton->progression[position].node;
}

void getCurrentAttributes(struct PARSED_AUTOMATON * parautomaton,
						 long ids[3], int types[3]){
	int position = parautomaton->nbnode-1;
	memcpy(ids,parautomaton->progression[position].objids,3*sizeof(long));
	memcpy(types,parautomaton->progression[position].objtypes,3*sizeof(int));
}

/* Printing methiods **************************************************/
void printNode(struct NODE * nod){
	int i;
	printf("  -%c ( ",nod->node);
	for(i=0;i<3;i++){
		if(nod->objtypes[i]>0){
			printf("%s%d ",typestr[nod->objtypes[i]],nod->objids[i]);
		}
	}
	printf(")\n");
}

void printAutomaton(struct PARSED_AUTOMATON * automat){
	int i;
	printf("Progression A:\n"); 
	for(i=0;i<automat->nbnode;i++){
		printNode(&automat->progression[i]);
	}
	printf("\n");
}


/* Update functions ***************************************************/
void setCurrentState(char s, struct PARSED_AUTOMATON * parautomaton){
	int position = parautomaton->nbnode-1;
	parautomaton->progression[position].node = s;
}

void addNode(struct PARSED_AUTOMATON * parautomaton,
			 char node, long ids[3], int types[3]){
	int size = parautomaton->nbnode;
	//printf("[+]start addNode\n");
	if(size>=parautomaton->nbmaxnode){
		void * ptr = parautomaton->progression;
		parautomaton->progression = calloc(size+NOD_CLUSTER_SIZE,
								           sizeof(struct NODE));
		memcpy(parautomaton->progression,ptr,size*sizeof(struct NODE));
		free(ptr);
		parautomaton->nbmaxnode += NOD_CLUSTER_SIZE;
	}
	parautomaton->nbnode++;
	parautomaton->progression[size].node = node;
	memcpy(parautomaton->progression[size].objids,ids,3*sizeof(long));
	memcpy(parautomaton->progression[size].objtypes,types,3*sizeof(int));
	//printf("[+]return from addNode\n");
}

void startAutomaton(struct PARALLEL_AUTOMATA * parautomata,
				    char node, long ids[3], int types[3]){
	int size = parautomata->nbnautomata;
	//printf("[+]start startAutomaton\n");
	//Reallocation d'espace
	if(size>=parautomata->nbmaxautomata){
		void * ptr = parautomata->automata;
		parautomata->automata = calloc(size+AUT_CLUSTER_SIZE,
			                           sizeof(struct PARSED_AUTOMATON));
		memcpy(parautomata->automata,ptr,size*sizeof(struct PARSED_AUTOMATON));
		free(ptr);
		parautomata->nbmaxautomata += AUT_CLUSTER_SIZE;
	}
	parautomata->nbnautomata++;
	parautomata->automata[size].nbnode = 0;
	parautomata->automata[size].nbmaxnode = 0;
	parautomata->automata[size].progression = NULL;
	addNode(&parautomata->automata[size],node,ids,types);
}

void deleteAutomaton(struct PARALLEL_AUTOMATA * parautomata, int index){
	struct PARSED_AUTOMATON * del; void * next; unsigned int nb;
	if(index+1<parautomata->nbnautomata){
		del = &parautomata->automata[index];
		next = &parautomata->automata[index+1];
		//free(del->progression);
		nb = (parautomata->nbmaxautomata-index)-1;
		/*buffer = calloc(nb,sizeof(struct PARSED_AUTOMATON));
		memcpy(buffer,next,nb*sizeof(struct PARSED_AUTOMATON));
		memcpy(del,buffer,nb*sizeof(struct PARSED_AUTOMATON));*/
		memcpy(del,next,nb*sizeof(struct PARSED_AUTOMATON));
	}
	parautomata->nbnautomata--;
}




